/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "绘图框架.h"

#include <vulkan/vulkan.h>


//S_板载缓存* S_光追后端::m_材质2 = nullptr;
S_板载缓存* S_光追后端::m_材质 = nullptr;
S_板载缓存* S_光追后端::m_帧渲染信息 = nullptr;

S_结构对象指针	S_光追后端::m_加速结构创建命令缓存 = {};
S_结构对象指针	S_光追后端::m_渲染Fence = {};


float32*          S_光追后端::m_f32_gpu_mapptr = nullptr;
int32*            S_光追后端::m_i32_gpu_mapptr = nullptr;
vec2*             S_光追后端::m_vec2_gpu_mapptr = nullptr;
vec3*             S_光追后端::m_vec3_gpu_mapptr = nullptr;
GLSL_RenderFrame* S_光追后端::m_mapPtr_渲染帧数据 = nullptr;
std::mutex        S_光追后端::g_资源分配内存锁;
E_离线渲染状态    S_光追后端::g_渲染状态 = E_离线渲染状态::e_光追渲染_关;

uint8 S_光追后端::g_光追列队 = 3;


S_子集绘图命令* S_绘图框架::g_资源加载管道 = nullptr;


std::vector<S_MapPtrItem> S_光追后端::G纹理;




S_绘图框架::S_绘图框架() {
	m_是否暂停 = true;
	//m_绘图设备配置 = nullptr;
}

void S_绘图框架::f_重置视口(void* 绘图设备, ivec2 size, E_MS次数 采样) {
	f_重置交换链(绘图设备, size, 采样);
}

S_着色::S_着色(const std::string& name) {
	m_ShaderIndex = -1;
}

S_线管::S_线管(const std::string& name) {
	m_Ctx = nullptr;
}

S_线管创建参数::S_线管创建参数(ivec2 viewSize) {
	m_视口大小 = viewSize;
	m_视口深度 = { 0.0f, 1.0f };
	m_视口数量 = 1;

	m_裁剪偏移 = { 0,0 };
	m_裁剪大小 = viewSize;

	m_采样 = E_MS次数::e_MS_1;
	m_绘制方式 = E_绘制方式::e_三角形;
	m_填充模式 = E_填充模式::e_填充面;
	m_透明混合模式 = E_混合模式::e_相加;
	m_颜色混合模式 = E_混合模式::e_相加;

	m_源颜色混合因子 = E_混合因子::e_源透明通道;
	m_目标颜色混合因子 = E_混合因子::e_源一减源透明通道;
	m_源透明通道因子 = E_混合因子::e_混合因子一;
	m_目标透明通道因子 = E_混合因子::e_混合因子零;

	m_深度偏移 = 0.0f;


	m_图元重启 = false;

	m_启用深度测试 = true;
	m_启用写入深度 = true;
	m_启用深度边界 = false;
	m_启用混合 = true;


}

uint32 f_getVk绘制方式(E_绘制方式 方式, E_绘图API apiName) {
	switch (方式)
	{
	case E_绘制方式::e_画点集:			return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
	case E_绘制方式::e_画线段:			return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
	case E_绘制方式::e_画连续线:		return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
	case E_绘制方式::e_三角形:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
	case E_绘制方式::e_三角形带:		return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
	case E_绘制方式::e_画扇形:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;

	case E_绘制方式::e_画邻接线段:		return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
	case E_绘制方式::e_画邻接连续线段:	return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
	default:
		break;
	}
	return 0xffffffff;
}

uint32 f_getVk填充方式(E_填充模式 方式, E_绘图API apiName) {
	switch (方式)
	{
	case E_填充模式::e_填充面:			return VK_POLYGON_MODE_FILL;
	case E_填充模式::e_填充点:			return VK_POLYGON_MODE_POINT;
	case E_填充模式::e_填充线:			return VK_POLYGON_MODE_LINE;
	default:
		break;
	}
	return 0xffffffff;
}

uint32 f_getVk混合模式(E_混合模式 模式) {
	switch (模式)
	{
	case E_混合模式::e_相加:		return VK_BLEND_OP_ADD;
	case E_混合模式::e_相减:		return VK_BLEND_OP_SUBTRACT;
	case E_混合模式::e_反向相减:	return VK_BLEND_OP_REVERSE_SUBTRACT;
	case E_混合模式::e_最小:		return VK_BLEND_OP_MIN;
	case E_混合模式::e_最大:		return VK_BLEND_OP_MAX;
	case E_混合模式::e_相乘:		return VK_BLEND_OP_MULTIPLY_EXT;
	case E_混合模式::e_零:			return VK_BLEND_OP_ZERO_EXT;
	case E_混合模式::e_源:			return VK_BLEND_OP_SRC_EXT;
	case E_混合模式::e_目标:		return VK_BLEND_OP_DST_EXT;
	case E_混合模式::e_反向:		return VK_BLEND_OP_INVERT_EXT;
	default:
		break;
	}
	return VK_BLEND_OP_MAX_ENUM;
}

uint32 f_getVk混合因子(E_混合因子 因子) {
	switch (因子)
	{
	case E_混合因子::e_混合因子零:			return VK_BLEND_FACTOR_ZERO;
	case E_混合因子::e_混合因子一:			return VK_BLEND_FACTOR_ONE;
	case E_混合因子::e_源颜色:				return VK_BLEND_FACTOR_SRC_COLOR;
	case E_混合因子::e_一减源颜色:			return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
	case E_混合因子::e_目标颜色:			return VK_BLEND_FACTOR_DST_COLOR;
	case E_混合因子::e_一减目标颜色:		return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
	case E_混合因子::e_源透明通道:			return VK_BLEND_FACTOR_SRC_ALPHA;
	case E_混合因子::e_源一减源透明通道:	return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
	case E_混合因子::e_目标透明通道:		return VK_BLEND_FACTOR_DST_ALPHA;
	case E_混合因子::e_一减目标透明通道:	return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
	default:
		break;
	}
	return VK_BLEND_FACTOR_MAX_ENUM;
}

uint32 f_get数据格式(E_数据格式 格式, E_绘图API apiName) {
	switch (格式) {
	case e_F_RGBA:
		return VK_FORMAT_R32G32B32A32_SFLOAT;
	case e_F_R32G32B32A32:
		return VK_FORMAT_R32G32B32A32_SFLOAT;
	case e_F_RGB:
		return VK_FORMAT_R32G32B32_SFLOAT;
	case e_F_R32G32:
		return VK_FORMAT_R32G32_SFLOAT;
	case e_F_R32:
		return VK_FORMAT_R32_SFLOAT;


	case e_I_R32G32B32A32:
		return VK_FORMAT_R32G32B32A32_SINT;
	case e_I_R32G32B32:
		return VK_FORMAT_R32G32B32_SINT;
	case e_I_R32G32:
		return VK_FORMAT_R32G32_SINT;
	case e_I_R32:
		return VK_FORMAT_R32_SINT;


	case e_UI_R32G32B32A32:
		return VK_FORMAT_R32G32B32A32_UINT;
	case e_UI_R32G32B32:
		return VK_FORMAT_R32G32B32_UINT;
	case e_UI_R32G32:
		return VK_FORMAT_R32G32_UINT;
	case e_UI_R32:
		return VK_FORMAT_R32_UINT;


	default:
		break;
	}
	return uint32();
}



/*void S_材质::f_alloc缓存槽(uint16 num) {
}

void S_材质::f_alloc纹理槽(uint16 num) {
}*/













S_材质::S_材质(S_设备环境* ctx) : m_Ctx(ctx) {
	m_Pipeline = nullptr;
	m_Shader = nullptr;
	
	m_深度遮挡 = true;
	m_GPU参数set = 0;

	mf_GPU参数配置		= nullptr;
	mf_GPU材质槽更新	= nullptr;

}

S_GPU计算::S_GPU计算(S_设备环境* ctx) {
	m_Pipeline = nullptr;
	m_Shader = nullptr;
	
	m_GPU参数set = 0;
	mf_GPU参数配置 = nullptr;
}









S_光追后端::S_光追后端() {
	m_Ctx                  = nullptr;
	m_光追管线             = nullptr;
	m_GPU参数设置          = nullptr;
	m_顶层加速结构         = nullptr;
	m_渲染纹理             = nullptr;
	m_渲染命令缓存         = nullptr;
	m_渲染Fence            = nullptr;
	m_加速结构创建命令缓存 = nullptr;
	m_场景物体网格指针         = nullptr;
	//m_帧渲染信息 = nullptr;
	m_绘图环境				= nullptr;
	
	m_材质             = nullptr;
	m_几何属性         = nullptr;

	m_全局绑定参数指针 = nullptr;
	m_I32动态属性      = nullptr;
	m_F32动态属性      = nullptr;
	m_Vec2动态属性     = nullptr;
	m_Vec3动态属性     = nullptr;
	m_Mat44动态属性    = nullptr;

	m_平行光缓冲区     = nullptr;
	m_点光源缓冲区     = nullptr;
	m_聚光灯缓冲区     = nullptr;
	m_区域光缓冲区     = nullptr;

	m_区域光物体网格   = nullptr;


	m_渲染             = true;
	m_重新编译线管     = false;

	m_mapPtr_渲染帧数据 = nullptr;


	
	m_预览渲染参数.光采样 = 6;
	m_预览渲染参数.反弹次数 = 4;
	m_预览渲染参数.采样次数 = 64;

	m_预览渲染参数.帧采样编号 = 0;
}

S_光追后端::~S_光追后端() {
	m_渲染 = false;
}

int32 S_光追后端::f_需要要加载纹理数() {
	return m_纹理绑定计数;
}

void S_光追后端::f_重置渲染帧记录() {
	if (m_帧渲染信息) {
		m_mapPtr_渲染帧数据->m_Frame = 0;
		//m_预览渲染参数.帧采样编号 = 0;
	}
}

void S_光追后端::f_递增渲染帧记录() {
	if (m_帧渲染信息) {
		++(m_mapPtr_渲染帧数据->m_Frame);
	}
}

void S_光追后端::f_mapGPU参数() {
	//m_f32_gpu_mapptr = f_buf_map板载缓存<float32>(m_F32动态属性);
	//m_i32_gpu_mapptr = f_buf_map板载缓存<int32>(m_I32动态属性);
	//m_vec2_gpu_mapptr = f_buf_map板载缓存<vec2>(m_Vec2动态属性);
	//m_vec3_gpu_mapptr = f_buf_map板载缓存<vec3>(m_Vec3动态属性);

	f_buf_map板载缓存<S_LigthParallel>(m_平行光缓冲区);
	f_buf_map板载缓存<S_LigthPoint>(m_点光源缓冲区);
	f_buf_map板载缓存<S_LigthArea>(m_区域光缓冲区);
	f_buf_map板载缓存<S_LigthSpot>(m_聚光灯缓冲区);
}

void S_光追后端::f_unmapGPU参数() {
	//f_buf_unmap板载缓存(m_F32动态属性);
	//f_buf_unmap板载缓存(m_I32动态属性);
	//f_buf_unmap板载缓存(m_Vec2动态属性);
	//f_buf_unmap板载缓存(m_Vec3动态属性);

	f_buf_unmap板载缓存(m_平行光缓冲区);
	f_buf_unmap板载缓存(m_点光源缓冲区);
	f_buf_unmap板载缓存(m_区域光缓冲区);
	f_buf_unmap板载缓存(m_聚光灯缓冲区);
}

void S_光追后端::f_resizeGPU参数() {
	//if (m_F32动态属性->m_分配器.maxNum)  f_buf_resize(m_F32动态属性, m_F32动态属性->m_分配器.maxNum);
	//if (m_I32动态属性->m_分配器.maxNum)  f_buf_resize(m_I32动态属性, m_I32动态属性->m_分配器.maxNum);
	//if (m_Vec2动态属性->m_分配器.maxNum) f_buf_resize(m_Vec2动态属性, m_Vec2动态属性->m_分配器.maxNum);
	//if (m_Vec3动态属性->m_分配器.maxNum) 
	//	f_buf_resize(m_Vec3动态属性, m_Vec3动态属性->m_分配器.maxNum);

	if (m_平行光缓冲区->m_分配器.maxNum) f_buf_resize(m_平行光缓冲区, m_平行光缓冲区->m_分配器.maxNum);
	if (m_点光源缓冲区->m_分配器.maxNum) f_buf_resize(m_点光源缓冲区, m_点光源缓冲区->m_分配器.maxNum);
	if (m_区域光缓冲区->m_分配器.maxNum) f_buf_resize(m_区域光缓冲区, m_区域光缓冲区->m_分配器.maxNum);
	if (m_聚光灯缓冲区->m_分配器.maxNum) f_buf_resize(m_聚光灯缓冲区, m_聚光灯缓冲区->m_分配器.maxNum);
}





